Conventional hardware register stacks associated with a central processing unit (CPU) are implemented so that a predetermined subset of general registers, or all of the general registers within the hardware register stack, are stacked when doing a subroutine call. The subroutine calls are started and ended by jump and branch instructions. The general registers are pushed onto the hardware register stack before executing the subroutine. The general registers are popped off the hardware register stack before leaving the subroutine.
An instruction set architecture (ISA) of the CPU provides specific definitions for some general registers. For example, one general register is a link register. The link register saves an address of the jump or the branch instruction that caused the subroutine to be executed. Consequently, the ISA-specific general registers should not be used by executable code.
Code compilers use the ISA-nonspecific general registers for predetermined purposes. The code compilers, however, commonly use only a portion of the available general registers. As a result, pushing and popping from the hardware register stack is inefficient. The general registers unused by the ISA and by the code compilers are pushed and popped from the hardware register stack though they do not contain useful information. Furthermore, the unused general registers cannot be used to hold global information that is common to multiple subroutines because the values change each time a push or a pop instruction occurs.
Predeterminations in the ISA and the code compilers for stacking of the general registers result in less-than-optimal performances for stacking operations. Speed of time critical applications such as exceptions handling routines and interrupt handling routines is limited by the stacking operations. Furthermore, application of multiple ISAs by the CPU is often difficult or impossible because of the limitations imposed by the ISA-specific general registers.